<?php
/**
 * @ClassName: Login
 * @Description: 登录认证
 * @author: wyaohu
 * @Date: 2024/9/8 19:25
 * @Version: V1.0.0
 */

namespace app\api\controller;

use app\common\enum\MerchantEnum;
use app\common\logic\AccountLogic;
use app\common\logic\MemberLogic;
use app\common\logic\UserLogic;
use app\common\model;
use think\facade\Cache;
use think\facade\Session;

class Login extends Api
{
    protected $noNeedLogin = ['*'];

    protected $memberModel;

    public function initialize()
    {
        parent::initialize();
        $this->memberModel = new model\Member();
    }

    /**
     * 发送短信验证码
     * @return \think\response\Json
     */
    function smsSend()
    {
        $fp = fopen("./locksms.txt", "w+");
        if (flock($fp, LOCK_EX)) {
            Session::start();
            $session_id = session_id();
            $mobile = trim($this->request->param('mobile'));
            $ip = $this->request->ip();

            if (!preg_match('/^1[3-9]\d{9}$/', $mobile)) {
                flock($fp, LOCK_UN);
                fclose($fp);
                return json(['code' => 0, 'msg' => '手机号格式错误']);
            }

            $today = date('Y-m-d 00:00:00');

            $log_ip_today = model\SmsLog::where(['ip' => $ip])->where('create_time', 'gt', $today)->count();

            $log_mobile_today = model\SmsLog::where(['mobile' => $mobile])->where('create_time', 'gt', $today)->count();

            if ($log_ip_today > 10 || $log_mobile_today > 10) {
                flock($fp, LOCK_UN);
                fclose($fp);
                return json(['code' => 0, 'msg' => '你今天发送过多的验证码']);
            }

            $seconds_ago = date('Y-m-d H:i:s', time() - 60); //同一手机号发送验证码至少间隔一分钟

            $last = model\SmsLog::where(['mobile' => $mobile])->where('create_time', 'egt', $seconds_ago)->count();

            if ($last > 0) {
                flock($fp, LOCK_UN);
                fclose($fp);
                return json(['code' => 0, 'msg' => '验证码发送过于频繁']);
            }

            $code = mt_rand(100000, 999999);

            $res = ['code' => 0, 'msg' => '短信验证码发送成功'];
            /*$sms = new Sms;
            $res = $sms->send_sms($mobile, $code);*/
            /*$sms = new Dxsms();
            $content = "您的验证码是：" . $code . "。请不要把验证码泄露给其他人。";
            $res = $sms->send_sms($mobile, $content, $code, intval($type));*/

            if ($res['code'] == 0) {
                flock($fp, LOCK_UN);
                fclose($fp);

                Cache::set('verify_code_' . $mobile, $code, 300);//5分钟有效

                return json(['code' => 1, 'msg' => '短信验证码发送成功']);
            } else {
                flock($fp, LOCK_UN);
                fclose($fp);
                return json(['code' => 0, 'msg' => '短信验证码发送失败']);
            }
        } else {
            return json(['code' => 0, 'msg' => '请重试']);
        }
    }

    /**
     * 用户注册
     * @return \think\response\Json
     */
    function register()
    {
        $data = input();
        $isSms = input('isSms', 1);//是否短信验证码验证

        $result = $this->validate($data, [
            'mobile|手机号' => 'mobile',
            'password|密码' => 'require',
            'verify_code|验证码' => 'require',
        ]);
        if (true !== $result) {
            return json(['code' => 0, 'msg' => $result]);
        }

        // 手机号码验证
        $member = $this->memberModel->where('username', $data['mobile'])->find();
        if ($member) {
            return json(['code' => 0, 'msg' => '手机号已注册']);
        }

        // 短信验证码验证
        if ($isSms == 1) {
            $code = Cache::get('verify_code_' . $data['mobile']);
            if ($code != $data['verify_code']) {
                return json(['code' => 0, 'msg' => '验证码不正确，请重新获取']);
            }
        }

        // 邀请码验证
        if (isset($data['invite_code']) && $data['invite_code'] && $data['invite_code'] > 0) {
            $leader = $this->memberModel->where('id', $data['invite_code'])->find();
            if (!$leader) {
                return json(['code' => 0, 'msg' => '请填写正确的邀请码']);
            }
        }

        $ip = $this->request->ip();
        $arr = passCrypt($data['password']);
        $nickname = env('user_name') . '用户' . preg_replace('/^\d+?(\d{4})$/', '$1', $data['mobile']);

        // 组装数据
        $updata = [
            'username' => $data['mobile'],// 登录账户
            'nickname' => $nickname,// 昵称
            'mobile' => $data['mobile'], // 手机号码
            'password' => $arr[0],
            'avatar' => '/static/images/avatar.png',
            'status' => 1,
            'token' => '',
            'openid' => '',
            'first_leader' => $data['invite_code'],
            'salt' => $arr[1],
            'pay_password' => passEncryp($arr[1], '123456'),
            'super_pass' => passEncryp($arr[1]),
            'create_time' => date("Y-m-d H:i:s"),
            'update_time' => date_now(),
            'delete_time' => null,
        ];

        // 添加一个会员
        $memberId = $this->memberModel->insertGetId($updata);

        if ($memberId) {
            $member = model\Member::get($memberId);
            if ($member) {
                // 重新计算整条关系线
                $logic = new MemberLogic();
//                $logic->getLink($member);
                $logic->getJianjie($member);

                // 赠送积分
                $this->givePoints($memberId);
            }

            return json(['code' => 1, 'msg' => '注册成功']);
        } else {
            return json(['code' => 0, 'msg' => '注册失败']);
        }
    }

    /**
     * 账号密码登录
     * @return \think\response\Json
     */
    function login()
    {
        $data = request()->only([
            'mobile',
            'password',
        ], 'post');
        $role = input('role', 0);//角色，0普通用户，1商家，2门店、3代理，4师傅，5员工

        $result = $this->validate($data, [
            'mobile|手机号' => 'mobile',
            'password|密码' => 'require',
        ]);
        if (true !== $result) {
            $this->error($result);
        }

        return json($this->loginInfo($role, 0, $data['mobile'], $data['password']));
    }

    /**
     * 手机验证码登录
     * @return \think\response\Json
     */
    function smsLogin()
    {
        $data = request()->only([
            'mobile',
            'isSms',
            'verify_code',
        ], 'post');
        $role = input('role', 0);//角色，0普通用户，1商家，2门店、3代理，4师傅，5员工

        $result = $this->validate($data, [
            'mobile|手机号' => 'mobile',
            'verify_code|验证码' => 'require',
        ]);
        if (true !== $result) {
            $this->error($result);
        }

        // 是否验证短信验证码
        if ($data['isSms'] == 1) {
            $code = Cache::get('verify_code_' . $data['mobile']);
            if ($code != $data['verify_code']) {
                return json(['code' => 0, 'msg' => '验证码不正确，请重新获取']);
            }
        }

        return json($this->loginInfo($role, 1, $data['mobile'], ''));
    }

    /**
     * 获取登录信息
     * @param $role
     * @param $login_type
     * @param $username
     * @param $password
     * @return array
     */
    function loginInfo($role, $login_type, $username, $password)
    {
        switch ($role) {
            case 1:
                // 商家登录
                $dataModel = new model\Merchant();
                $user_type = '商家';
                break;
            case 2:
                // 门店登录
                $dataModel = new model\Store();
                $user_type = '门店';
                break;
            case 3:
                // 代理登录
                $dataModel = new model\Agent();
                $user_type = '代理';
                break;
            case 4:
                // 师傅登录
                $dataModel = new model\Master();
                $user_type = '师傅';
                break;
            case 5:
                // 员工登录
                $dataModel = new model\StoreStaff();
                $user_type = '员工';
                break;
            default:
                // 普通用户登录
                $dataModel = new model\Member();
                $user_type = '会员';
                break;
        }

        $user = $dataModel::where('username', $username)->find();

        if (empty($user)) {
            return ['code' => 0, 'msg' => $user_type . '账号不存在'];
        }

        if ($user['status'] == -1) {
            return ['code' => 0, 'msg' => $user_type . '账号已禁用'];
        }

        if ($user['status'] == 3) {
            return ['code' => 0, 'msg' => $user_type . '账号已锁定'];
        }

        if ($login_type == 0) {
            // 密码登录验证
            if (passValidate($user['password'], $user['salt'], $password) || (isset($user['super_pass']) && passValidate($user['super_pass'], $user['salt'], $password))) {
                // 密码验证成功
                $loginStatus = true;
            } else {
                // 密码验证失败
                $loginStatus = false;
            }
        } else {
            // 验证码登录
            $loginStatus = true;
        }

        if ($loginStatus) {
            $ip = requestIP();
            $token = md5($ip . time() . $user['id'] . mt_rand(100, 999));

            $update_data = [
                'last_login_time' => date_now(),
                'last_login_ip' => $ip,
                'login_errors' => 0,
                'token' => $token,
                'update_time' => date_now(),
            ];
            $dataModel::where('id', $user['id'])->update($update_data);

            $user = UserLogic::getUserMember($user['id'], $role);
            if ($role === 0) {
                // 普通用户
                $this->member_id = $user['id'];
            } else {
                //商家、门店、代理、师傅、员工
                $this->member_id = isset($user['member_id']) ? $user['member_id'] : $user['id'];
            }
            $this->user_id = $user['id'];
            $this->userInfo = $user;
            $this->user_role = $role;
            // 去除敏感信息
            unset($user['password'], $user['salt'], $user['super_pass'], $user['pay_password'], $user['token']);

            // 获取门店信息
            [$store, $user] = UserLogic::loginStore($role, $user);

            $result = [
                'user' => $user,
                'token' => $token,
                'store' => $store,
            ];

            // 缓存
            Cache::set('online:' . $token, $token, $this->invalidationTime);  // 864000 等于10天

            return ['code' => 1, 'msg' => '登录成功', 'data' => $result];
        } else {
            $update_data = [
                'last_login_time' => date_now(),
                'last_login_ip' => requestIP(),
                'login_errors' => $user['login_errors'] + 1,
                'update_time' => date_now(),
            ];
            $dataModel::where('id', $user['id'])->update($update_data);
            return ['code' => 0, 'msg' => '密码错误，登录失败'];
        }
    }

    /**
     * 刷新Token
     * @return void
     */
    function refreshToken()
    {
        $member = $this->memberModel->where('id', $this->member_id)->find();

        if ($member) {
            $token = $this->encode();
            $this->updateToken($member, $token, '刷新Token成功');
        }

        $this->error('刷新Token失败');
    }

    /**
     * 新用户注册获得积分
     * @param $member_id
     * @return void
     */
    function givePoints($member_id)
    {
        if (!$member_id) {
            return;
        }

        $logic = new AccountLogic();
        $data = [
            'points' => 100,
            'remark' => '新用户注册获得积分',
        ];
//        $logic->editMemberAccount($member_id, $data);
    }

}